use anyhow::Ok;
use opencv::core::Vector;
use opencv::imgcodecs::imwrite;
use opencv::videoio;
use opencv::videoio::VideoCaptureProperties;
use opencv::{imgproc, prelude::*};

const VIDEO_PATH: &str = "/home/jaakan/下载/超级飞侠9/15.mp4";

#[test]
fn read_1() -> anyhow::Result<()> {
    let mut video_cap = videoio::VideoCapture::from_file(VIDEO_PATH, videoio::CAP_ANY).unwrap();

    let opened = videoio::VideoCapture::is_opened(&video_cap)?;
    if !opened {
        panic!("Unable to open default camera!");
    }

    print_video_info(&video_cap);

    for _ in 0..30 {
        // 后移一帧
        video_cap.grab().unwrap();
        print_video_info(&video_cap);
    }

    let frame_count = video_cap
        .get(VideoCaptureProperties::CAP_PROP_FRAME_COUNT as i32)
        .unwrap();
    println!("frame_count={frame_count}");

    let mut frame = Mat::default();
    video_cap.retrieve(&mut frame, 0).unwrap();

    // total=654480
    // flags=1124024336
    // size=Size_ { width: 1080, height: 606 }
    // total = width x height
    println!("total={}", frame.total());
    let flags = frame.flags();
    println!("flags={}", flags);
    let size = frame.size().unwrap();
    println!("size={:?}", size);

    let params = vec![flags];
    let params = Vector::from_slice(&params[..]);
    imwrite("./RGB.jpg", &frame, &params).unwrap();

    // BGR图片转灰度图
    let mut gray = Mat::default();
    imgproc::cvt_color(&frame, &mut gray, imgproc::COLOR_BGR2GRAY, 0)?;
    imwrite("./GRAY.jpg", &gray, &params).unwrap();

    video_cap.release().unwrap();

    Ok(())
}

fn print_video_info(video_cap: &videoio::VideoCapture) {
    // https://docs.rs/opencv/0.82.1/opencv/videoio/enum.VideoCaptureProperties.html
    let fps = video_cap
        .get(VideoCaptureProperties::CAP_PROP_FPS as i32)
        .unwrap();

    let frame_count = video_cap
        .get(VideoCaptureProperties::CAP_PROP_FRAME_COUNT as i32)
        .unwrap();

    let pos_ms = video_cap
        .get(VideoCaptureProperties::CAP_PROP_POS_MSEC as i32)
        .unwrap();

    // Relative position of the video file: 0=start of the film, 1=end of the film.
    let pos_avi_ratio = video_cap
        .get(VideoCaptureProperties::CAP_PROP_POS_AVI_RATIO as i32)
        .unwrap();

    // 当前帧
    let pos_frames = video_cap
        .get(VideoCaptureProperties::CAP_PROP_POS_FRAMES as i32)
        .unwrap();

    println!(
        "视频信息:
 > fps={fps}, frame_count={frame_count}, pos_ms={pos_ms}, pos_avi_ratio={pos_avi_ratio}, pos_frames={pos_frames}"
    );
}

#[test]
fn start_and_end() {
    let mut video_cap = videoio::VideoCapture::from_file(VIDEO_PATH, videoio::CAP_ANY).unwrap();

    let opened = videoio::VideoCapture::is_opened(&video_cap).unwrap();
    if !opened {
        panic!("Unable to open default camera!");
    }

    let backend_name = video_cap.get_backend_name();
    println!("backend_name={backend_name:?}");

    // 跳到指定的时间
    let _ = videoio::VideoCapture::set(
        &mut video_cap,
        VideoCaptureProperties::CAP_PROP_POS_MSEC as i32,
        800_000.0_f64,
    )
    .unwrap();

    // print_video_info(&video_cap);
    loop {
        let grab = match video_cap.grab() {
            Err(err) => {
                eprintln!("err={err:?}");
                false
            }
            Result::Ok(grab) => grab,
        };

        if !grab {
            println!("======  END =======");
            video_cap.release().unwrap();
            break;
        }

        println!("grab={grab}");

        print_video_info(&video_cap);
    }
}

#[test]
fn read_2() {
    let xml = opencv::core::find_file("haarcascades/haarcascade_frontalface_alt.xml", true, false);
    println!("{xml:?}");
}
